Zaki Mirza’s Blog

Icon

… About software and beyond!

Visual Studio Add-in : Creating Context Menus


Note: I assume basic knowledge of what Visual Studio Add-ins are and how to create a sample add-in and tweak it.

There are several articles around the internet that will get you up and started with creating a visual studio add-in (sorry to say, most of them are just rip-offs of the stock-msdn-walk-through on how to create a visual studio add-in from the extensibility wizard). I present here my findings (the hard way, due to lack of proper documentation of these things).

So you have decided to create a visual studio add-in and know what you want to add where. Let’s take the simplified form of what I created and while we do this, we will come across issues that you might not find answer of elsewhere (at least I couldn’t).

Most add-ins require a Menu Items to be added in the main toolbar. Now I’m not going to tell you about how to do that since there are several articles on that already (heck even the walk-through that comes with MSDN tells you how to do that). I’m going to tell you how to add a button anywhere in the visual studio environment (say, on a context menu).

Visual studio IDE is basically made up of Command bars (represented by the Microsoft.VisualStudio.CommandBars.CommandBar interface). These command  bars can be enumerated using the following snippet. You should be familiar with these things if you have worked on a visual studio add-in before.

_applicationObject = (DTE2)application;
CommandBars cBars =  (CommandBars)_applicationObject.CommandBars;

So to get the “Menu Bar” command bar (which is the default menu bar of visual studio containing File, Edit, View etc.) and the View drop down, you can do

CommandBar editorCommandBar = (CommandBar)cBars["MenuBar"];
CommandBarPopUp editPopUp = (CommandBarPopUp)editorCommandBar.Controls["&View"];

And to get the code editor windows context menu “Command bar” you will have to do:

CommandBar editorCommandBar = (CommandBar)cBars["Editor Context Menus"];
CommandBarPopUp editPopUp = (CommandBarPopUp)editorCommandBar.Controls["Code Window"];

and to add a context menu anywhere on these pop-up command bars,

Command command = commands.AddNamedCommand2(_addInInstance,
 "test", "test", "Executes the command for test", true, 59, ref contextGUIDS,
 (int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.vsCommandStatusEnabled,
 (int)vsCommandStyle.vsCommandStylePictAndText,
 vsCommandControlType.vsCommandControlTypeButton);

command.AddControl(editPopUp.CommandBar, 1);

This should add a context menu button in you code editor window’s right click. My first instinct would be knowing how can I get a reference to a specific Command Bar and what exactly is a command bar? (And thats exactly what you should be asking right now “how the heck did I know that there exists such a thing as “Editor Context Menus“??)

Answer is in knowing what command bars are available to you. So what is a command bar? Are these the dockable command bars on the top of IDE? Nope. Well yes, they are too but there are several hidden command bars in visual studio IDE as well through which we will add our context menus.

Tip:

You can try debug your add-in and see what is contained in this collection of _applicationObject.CommandBars, but you will end up lost since you can never see inside the enumeration since they are exposed as Com Objects. What you can do is, use the handy print-to-output-window snippet like the following: (a sample dump i create can be found here)


foreach (CommandBar c in
         ((CommandBars)_applicationObject.CommandBars))
{
    foreach (CommandBarControl ctrl in c.Controls)
    {
         OutputWindowPane pane =
         _applicationObject.ToolWindows.OutputWindow.ActivePane;
         pane.OutputString (c.Name);
         pane.OutputString (" : ");
         pane.OutputString (ctrl.Caption);
         pane.OutputString (" : ");
         pane.OutputString (ctrl.Type.ToString ());
         pane.OutputString (" \n ");
    }
}


From here on you can see the “hidden” names of all Command Bars and try guessing which corresponds to what [the output will show up in the output window pane]. For example, if I were to add a context menu to the Call Stack Window context menu i know that these are on the menu for the debugger context menus toolbar:

 Debugger Context Menus : Autos Window : msoControlPopup
 Debugger Context Menus : Breakpoint : msoControlPopup
 Debugger Context Menus : Breakpoints Window : msoControlPopup
 Debugger Context Menus : Call Stack Window : msoControlPopup 
 Debugger Context Menus : Data Tip Window : msoControlPopup
 Debugger Context Menus : Disassembly Window : msoControlPopup
 Debugger Context Menus : Locals Window : msoControlPopup
 Debugger Context Menus : Memory Window : msoControlPopup
 Debugger Context Menus : Modules Window : msoControlPopup
 Debugger Context Menus : Output Window : msoControlPopup
 Debugger Context Menus : Processes Window : msoControlPopup
 Debugger Context Menus : Registers Window : msoControlPopup
 Debugger Context Menus : Threads Window : msoControlPopup
 Debugger Context Menus : Watch Window : msoControlPopup 

So that would be:



 CommandBar debuggerContextCommandBar =
     (CommandBar)cBars["Debugger Context Menus"];

 CommandBarPopUp callStackPopUp =
 (CommandBarPopUp)editorCommandBar.Controls["Call Stack Window"];

 Command command = commands.AddNamedCommand2 (_addInInstance,
  "mycallstack", "mycallstack",
  "Executes the command for test", true, 59, ref contextGUIDS,
  (int)vsCommandStatus.vsCommandStatusSupported +
  (int)vsCommandStatus.vsCommandStatusEnabled,
  (int)vsCommandStyle.vsCommandStylePictAndText,
  vsCommandControlType.vsCommandControlTypeButton);

 command.AddControl (callStackPopUp.CommandBar, 1);



If you try out your project now, you should be able to see a shiny brand new smiley enabled context menu in the call stack window (while debugging ofcourse).

Now in the EXec Method, you should be able to catch whenever this command is executed:

public void Exec(string commandName,
 vsCommandExecOption executeOption,
 ref object varIn, ref object varOut,
 ref bool handled)
 {
 handled = false;
 if (executeOption ==
     vsCommandExecOption.vsCommandExecOptionDoDefault)
     {
     if (commandName == "test.Connect.mycallstack")
         {
         handled = true;
         return;
         }
     }
 }

A very useful resource for visual studio add-in is a comprehensive set of tutorials here. From here-on you can create a context menu, and get the exec code for it and do your computation. There are several other issues that you might need to look at :). I would fill the gaps if time permits.

Till then, happy extending visual studio 🙂

Filed under: programming, Troubleshooter, visual studio, , , , , ,

10 Responses

  1. Veryon says:

    This one was pretty interesting..

  2. Sÿl says:

    Yes interesting but there’s a probleme with VS2008 : the first time you execute this, this new command does not appear ! You have to restart VS then it works. Any fix about this ?

  3. Dave Haynes says:

    I can’t get “Editor Context Menus” to work. Nothing shows up… 😦

    Also, you might try BlogTrog.com to display your source code.

  4. Mark C says:

    I couldn’t get it to work but I did get a great deal on valium.

  5. dav says:

    it doesn’t work on VS 2008, no menu.

  6. Pol33 says:

    Instead, I will refer SB readers to the quick, 10-question survey I created, and look forward to sharing and discussing results. ,

  7. Daddy27 says:

    I sort of had a feeling of being a little overwhelmed. ,

  8. vasilijvani says:

    Добрый день!

    Я видел упоминание курса осознанных снов тут. Надеюсь, что будет полезным.

Leave a comment

RSS Google Shared Items

  • An error has occurred; the feed is probably down. Try again later.

RSS Google Reader Starred Items

  • An error has occurred; the feed is probably down. Try again later.

Top Clicks

  • None